package org.greatlogic.gwtfilereaderwidget.client.itunes;

import java.util.ArrayList;
import org.greatlogic.gwtfilereaderwidget.client.itunes.ITunesEnums.EConjunction;

class ConditionParentNode implements IConditionNode {
//--------------------------------------------------------------------------------------------------
private ArrayList<IConditionNode> _childNodeList;
private EConjunction              _firstChildConjunction;
private ConditionParentNode       _parentNode;
//--------------------------------------------------------------------------------------------------
ConditionParentNode() {
  _childNodeList = new ArrayList<IConditionNode>();
  _firstChildConjunction = EConjunction.Unknown;
} // ConditionParentNode()
//--------------------------------------------------------------------------------------------------
void addChildNode(final IConditionNode childNode) {
  // set the parent node conjunction to the child node conjunction if this is the first child of
  // the parent
  ConditionParentNode parentNode = this;
  while (parentNode != null && parentNode._firstChildConjunction == EConjunction.Unknown) {
    parentNode._firstChildConjunction = childNode.getConjunction();
    parentNode = parentNode._parentNode;
  }
  _childNodeList.add(childNode);
  childNode.setParentNode(this);
} // addChildNode()
//--------------------------------------------------------------------------------------------------
@Override
public boolean evaluate(final Track track) throws ITunesException {
  boolean result = true;
  for (int nodeIndex = 0; nodeIndex < _childNodeList.size(); ++nodeIndex) {
    IConditionNode node = _childNodeList.get(nodeIndex);
    if (nodeIndex > 0 && //
        ((result && node.getConjunction() == EConjunction.Or) || //
        !result && node.getConjunction() == EConjunction.And)) {
      nodeIndex = _childNodeList.size();
    }
    else {
      result = node.evaluate(track);
    }
  }
  return result;
} // evaluate()
//--------------------------------------------------------------------------------------------------
ArrayList<IConditionNode> getChildNodeList() {
  return _childNodeList;
} // getChildNodeList()
//--------------------------------------------------------------------------------------------------
@Override
public EConjunction getConjunction() {
  return _firstChildConjunction;
} // getConjunction()
//--------------------------------------------------------------------------------------------------
@Override
public ConditionParentNode getParentNode() {
  return _parentNode;
} // getParentNode()
//--------------------------------------------------------------------------------------------------
@Override
public void setParentNode(final ConditionParentNode parentNode) {
  _parentNode = parentNode;
} // setParentNode()
//--------------------------------------------------------------------------------------------------
@Override
public String toString() {
  String result = "";
  if (!_childNodeList.isEmpty()) {
    if (_parentNode != null) {
      if (this != _parentNode._childNodeList.get(0)) {
        result = _firstChildConjunction.getToStringValue() + " ";
      }
      result += "(";
    }
    for (IConditionNode node : _childNodeList) {
      if (node instanceof ConditionLeafNode ||
          ((ConditionParentNode)node)._childNodeList.size() > 0) {
        result += (node == _childNodeList.get(0) ? "" : " ") + node.toString();
      }
    }
    if (_parentNode != null) {
      result += ")";
    }
  }
  return result;
} // toString()
//--------------------------------------------------------------------------------------------------
}